home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / hf / dsp / source / pam.new < prev    next >
Encoding:
Text File  |  1991-06-29  |  10.7 KB  |  456 lines

  1.     page    132,63,1,1
  2.     opt    rc
  3.     title    'PAM Modulation/Demodulation'
  4.  
  5. ;***************************************************************
  6. ;* PAM.ASM -- PAM Modulation/Demodulation and               *
  7. ;*          SSI drivers                       *
  8. ;*                                   *
  9. ;* Provides interrupt based SSI handling, sample buffering     *
  10. ;* and PAM modulation and demodulation.                *
  11. ;*                                   *
  12. ;* PAM modulation and demodulation is based on some ideas      *
  13. ;* presented in book                           *
  14. ;*    Lee, E., A., Messerschmitt, D., G.:               *
  15. ;*    "Digital Communication",                   *
  16. ;*    Kluwer, 1988                           *
  17. ;*                                   *
  18. ;* Symbol syncronization is based on article               *
  19. ;*    Glisic, S., G.:                        *
  20. ;*    "Symbol Syncronization in Digital Communications       *
  21. ;*     Using Partial Response CPM signaling",                *
  22. ;*    IEEE Trans. on Comm., Vol. 37, No. 3, March 1989       *
  23. ;*                                   *
  24. ;* This module uses registers as follows:               *
  25. ;*  r0 - general purpose (temporary use)               *
  26. ;*  r2 - input sample write pointer                   *
  27. ;*  r3 - output sample read pointer                   *
  28. ;*  r4 - general purpose (temporary use)               *
  29. ;*  r6 - input sample read pointer                   *
  30. ;*  r7 - output sample write pointer                   *
  31. ;*                                   *
  32. ;* Copyright (C) 1991 by Alef Null. All rights reserved.       *
  33. ;* Author(s): Jarkko Vuori, OH2LNS                   *
  34. ;* Modification(s):                           *
  35. ;***************************************************************
  36.  
  37.     nolist
  38.     include 'ioequlc'
  39.     list
  40.  
  41.     section PAM
  42.     xdef    ssi_ini,modem_i
  43.     xdef    m_loop
  44.     xref    putbit,getbit
  45.     xref    m_cra,m_crb,m_tde,m_sr,m_tx
  46.  
  47.     org    p:
  48.  
  49.     nolist
  50.     include 'macros'
  51.     list
  52.  
  53. ; PAM sync parameters
  54. poly    equ    $10010                    ; G3RUH,K9NG scrambler polynomial (x^17 + x^12 + 1)
  55. cM0    equ     6                    ; random walk filter constant
  56. adjlen    equ    18                    ; ADC timing control lenght (in samples)
  57. analen    equ    32                    ; sample quality analyzing lenght
  58.  
  59. ; module status bits
  60. toggle    equ    6                    ; every other bit counter
  61.  
  62. ; first order high-pass IIR filter
  63. ; input in a, output in a
  64. ; frq is -3dB point (fc/fs)
  65. hpass    macro    acc,frq,store
  66. c1    set    -1.0/@cos(6.28319*frq)*(1.0-@sin(6.28319*frq))
  67.     move            acc,x0
  68.     move            #(1.0-c1)/2.0,x1
  69.     mpyr    x0,x1,acc   x:<store,x1
  70.     move            acc,x:<store
  71.     sub    x1,acc        x:<store+1,x0
  72.     move            #c1,x1
  73.     macr    -x0,x1,acc
  74.     move            acc,x:<store+1
  75.     endm
  76.  
  77. ; first order low-pass IIR filter
  78. ; input in a, output in a
  79. ; frq is -3dB point (fc/fs)
  80. lpass    macro    acc,frq,store
  81. c1    set    -1.0/@cos(6.28319*frq)*(1.0-@sin(6.28319*frq))
  82.     move            acc,x0
  83.     move            #(1.0+c1)/2.0,x1
  84.     mpyr    x0,x1,acc   x:<store,x1
  85.     move            acc,x:<store
  86.     add    x1,acc        x:<store+1,x0
  87.     move            #c1,x1
  88.     macr    -x0,x1,acc
  89.     move            acc,x:<store+1
  90.     endm
  91.  
  92.  
  93. ;****************************
  94. ;*    SSI initialization    *
  95. ;****************************
  96. ssi_ini
  97. ; initialize SSI,
  98.     IF    !DEBUG
  99.     movep            #$4000,x:m_cra        ; 16 bit word
  100.     movep            #$f200,x:m_crb        ; syncronous,word frame,ext clk
  101.     ELSE
  102.     movep            #$4011,x:m_cra        ; 16 bit word, abt. 19.2 ksamples/s
  103.     movep            #$f620,x:m_crb        ; syncronous,word frame,ext clk
  104.     ENDIF
  105.  
  106.     rts
  107.  
  108.  
  109. ;****************************
  110. ;*      ADC & MODEM        *
  111. ;*    initialization        *
  112. ;****************************
  113. modem_i
  114. ; program the A/D & D/A converter chip (TLC32044, master clock is 5.184MHz)
  115. ; disable A/D high-pass filter, disable loopback, disable AUX IN,
  116. ; select syncronous mode, select input span 3Vpp, insert sinx/x correction
  117. ; lowpass cutoff frequency at    6840Hz -> TA  =  5 (SCF = 518.4kHz)
  118. ; sampling frequency is        19200Hz -> TB  = 27
  119. ; unit sampling correction time  0.6uS -> TA' =  3
  120.     pgmtlc    %10101000,5,3,27
  121.  
  122. ; sample handling,
  123.     move            #<insamp,r6
  124.     move            #<inN-N,n6
  125.     move            #<inN-1,m6
  126.     move            r6,r2
  127.     move            m6,m2
  128.     movi    0,x:<samque
  129.  
  130.     move            #<outsamp,r3
  131.     move            #<outN-1,m3
  132.     move            #<outsamp+1,r7
  133.     move            m3,m7
  134.     movi    <outfilt,x:<outfptr
  135.  
  136. ; symbol syncro logic,
  137.     movi    cM0,x:<rwalk
  138.     movi    analen,x:<anacnt
  139.     movi    0,x:<goodcnt
  140.  
  141. ; ADC command word
  142.     movi    0,x:<adcnt
  143.  
  144.     rts
  145.  
  146.  
  147. ;****************************
  148. ;*      Main Loop        *
  149. ;****************************
  150. loop    wait
  151. m_loop
  152.  
  153.  
  154. ;****************************
  155. ;*      Receiver        *
  156. ;****************************
  157. ; check if there are new samples received
  158. rec    move            r2,a
  159.     move            r6,x0
  160.     cmp    x0,a        #<rcos,r0
  161.     jeq    <xmit
  162.  
  163. ; yes, there indeed are new samples, check if receiver enabled
  164.     jset    #ptt,x:<status,xmit
  165.  
  166. ; receive squared raised cosine filter
  167.     conv    1,N,r6,r0,a
  168.  
  169. ; remove any DC-level (with high-pass filter)
  170.     hpass    a,40.0/19200.0,rdc
  171.  
  172. ; limit to binary and queue received bits
  173.     andi    #$fe,ccr
  174.     jmi    <ssi_r00
  175.     ori    #$01,ccr
  176. ssi_r00 move            x:<samque,b1
  177.     rol    b        (r6)+n6
  178.     move            b1,x:<samque
  179.  
  180. ; queue received samples
  181.     move            y:<pzsample,b1
  182.     move            b1,y:<pdsample
  183.     move            y:<dsample,b1
  184.     move            b1,y:<pzsample
  185.     move            y:<zsample,b1
  186.     move            b1,y:<dsample
  187.     move            a,y:<zsample
  188.  
  189. ; check if one symbol (2 samples) received
  190.     bchg    #toggle,x:<status
  191.     jcc    <ssi_end
  192.  
  193. ; check if carrier present
  194. ; by checking when eye is open
  195. ; (enought difference between zero crossing sample and decision sample)
  196.     move            y:<dsample,a        ; filter decision samples
  197.     abs    a
  198.     lpass    a,40.0/19200.0,rds
  199.  
  200.     move            y:<zsample,b        ; filter zero crossing samples
  201.     abs    b
  202.     lpass    b,40.0/19200.0,rzs
  203.  
  204.     sub    b,a        #>2500,x0            ; check their difference
  205.     cmpm    x0,a
  206.     jhs    <ssi_r0a
  207.  
  208.     bclr    #dcd,x:<status                ; dcd off
  209.     jcc    <ssi_r0b
  210.     dcdoff
  211.     jsset    #req,x:<status,kickx            ; call persistence routine if needed
  212.     jmp    <ssi_r0b
  213. ssi_r0a bset    #dcd,x:<status                ; dcd on
  214.     jcs    <ssi_r0b
  215.     dcdon
  216.  
  217. ssi_r0b
  218. ; experimental symbol syncro
  219.     move            y:<dsample,a        ; calculate decision difference
  220.     tst    a        #-1.0,x0
  221.     move            #0.999999,a
  222.     tmi    x0,a
  223.     move            y:<pdsample,b
  224.     tst    b                    ; limit to -1.0 or 1.0
  225.     move            #0.999999,b
  226.     tmi    x0,b
  227.     sub    b,a
  228.  
  229.     move            a,x1            ; calculate and smooth clock adjust term
  230.     move            y:<pzsample,x0
  231.     mpy    x0,x1,a
  232.     lpass    a,3.0/9600.0,rsym
  233.  
  234.     move            #>8000,x0            ; if spesified threshold is
  235.     cmpm    x0,a                    ; met, adjust timing
  236.     jlo    <ssi_yyy
  237.     tst    a
  238.     jpl    <ssi_xxx
  239.     movib            retard,x:<adccmd
  240.     movib            adjlen,x:<adcnt
  241.     jmp    <ssi_yyy
  242. ssi_xxx movib            advance,x:<adccmd
  243.     movib            adjlen,x:<adcnt
  244.     jmp    <ssi_yyy
  245.  
  246. ssi_yyy swi
  247.     jmp    <ssi_r4
  248.  
  249. ; check if there are transitions (by analyzing the sample between decision samples)
  250. ; (...X|*X|*X|*...)
  251. ;   where X decision sample
  252. ;      * analyzed sample
  253. ;      | symbol boundaries
  254.     move            #>-1,x1
  255.     clr    a        #>1,x0
  256.     jclr    #1,x:<samque,ssi_l1
  257.     jset    #3,x:<samque,ssi_le
  258. ; 0x1
  259.     move            x0,a
  260.     btst    #2,x:<samque
  261.     tcc    x1,a
  262.     jmp    <ssi_le
  263. ssi_l1    jclr    #3,x:<samque,ssi_le
  264. ; 1x0
  265.     move            x1,a
  266.     btst    #2,x:<samque
  267.     tcc    x0,a
  268.  
  269. ; symbol syncro
  270. ssi_le    tst    a        x:<rwalk,x0
  271.     jeq    <ssi_r4
  272.     add    x0,a        #>2*cM0,x0
  273.     jpl    <ssi_r2
  274. ; retard sampling
  275.     move            #cM0,a1
  276.     movib            retard,x:<adccmd
  277.     movib            adjlen,x:<adcnt
  278.     jmp    <ssi_r3
  279. ;
  280. ssi_r2    cmp    x0,a
  281.     jle    <ssi_r3
  282. ; advance sampling
  283.     move            #cM0,a1
  284.     movib            advance,x:<adccmd
  285.     movib            adjlen,x:<adcnt
  286. ;
  287. ssi_r3    move            a1,x:<rwalk
  288.  
  289. ; unscramble symbol, result in C
  290. ssi_r4    btst    #1,x:<samque
  291.     move            x:<usrem,b1
  292.     jcc    <unscram
  293.     move            #>(poly<<1)|1,x0
  294.     eor    x0,b
  295. unscram lsr    b
  296.     move            b1,x:<usrem
  297.  
  298. ; make symbol decision (with NRZ-S decoding), databit in C, result in C
  299.     rol    b        x:<prvrsym,x0
  300.     eor    x0,b        b1,x:<prvrsym
  301.     not    b
  302.     lsr    b
  303.  
  304. ; forward to the HDLC handler
  305.     jsr    <putbit
  306.  
  307. ssi_end jmp    <rec
  308.  
  309.  
  310. ;****************************
  311. ;*     Transmitter        *
  312. ;****************************
  313. ; check if we can calculate new samples
  314. xmit    move            r3,a
  315.     move            r7,x0
  316.     cmp    x0,a
  317.     jeq    <loop
  318.  
  319. ; yes, check if the transmitter is on at all
  320.     clr    a
  321.     jclr    #ptt,x:<status,xmt2
  322.  
  323. ; xmit mode, check if we need a new symbol
  324.     bchg    #toggle,x:<status
  325.     jcc    <xmt1
  326.  
  327. ; yes, check on what phase we are
  328.     jset    #xmt,x:<status,xmt0
  329.  
  330. ; training phase, send continuous preamble (zero pattern)
  331.     andi    #$fe,ccr
  332.     jmp    <morebit
  333.  
  334. ; data phase, get a new bit to xmit
  335. xmt0    jsr    <getbit
  336.     jne    <morebit
  337. ; there is no more bits to send, switch to receiving mode
  338.     jsr    <shutx
  339.     jmp    <scx_end
  340.  
  341. ; NRZ-S coding
  342. morebit rol    a        x:<prvxsym,x0
  343.     not    a
  344.     eor    x0,a        #-1.0,x0
  345.     ror    a        a1,x:<prvxsym
  346.  
  347. ; scrambler, databit in C flag, result in a (-1 or 1)
  348.     clr    a
  349.     rol    a        x:<srem,x0
  350.     eor    x0,a        #-0.9,x1
  351.     lsr    a        #>poly,x0
  352.     jcc    <scram
  353.     eor    x0,a
  354. scram    move            a1,x:<srem
  355.     move            #0.9,a
  356.     tcc    x1,a
  357.  
  358. ; squared raised cosine shape output filter
  359. xmt1    move            x:<outfptr,r4
  360.     move            #<rcos,r0
  361.     move            #<N-1,m4
  362.     move            a,x:(r4)
  363.     conv    1,N,r4,r0,a
  364.     move            r4,x:<outfptr
  365.     move            #-1,m4
  366.  
  367. ; send a new bit
  368.     move            a,x0            ; adjust output level
  369.     move            x:<gain,x1
  370.     mpyr    x0,x1,a     #>$fffc<<8,x0
  371. xmt2    and    x0,a        x:<adcnt,b
  372.     tst    b        #>1,y0            ; check if we must adjust timing
  373.     jeq    <xmt3
  374.     sub    y0,b        x:<adccmd,x0        ; yes, add converter chip control cmds
  375.     or    x0,a        b1,x:<adcnt
  376. xmt3    move            a,x:(r7)+
  377.  
  378. scx_end jmp    <xmit
  379.  
  380.  
  381. ;****************************
  382. ;*     DATA - AREA        *
  383. ;****************************
  384.  
  385.     org    x:
  386.  
  387. adccmd    ds    1                    ; ADC timing command
  388. adcnt    ds    1                    ; ADC timing command counter
  389. samque    ds    1                    ; received sample queue
  390. prvrsym ds    1                    ; previous received symbol
  391. prvxsym ds    1                    ; previous xmitted symbol
  392. rwalk    ds    1                    ; random walk filter counter
  393. rds    ds    2                    ; runnning average
  394. rzs    ds    2                    ; runnning average
  395. rdc    ds    2                    ; DC-level filter
  396. rsym    ds    2
  397. anacnt    ds    1                    ; signal quality analyzing lenght counter
  398. goodcnt ds    1                    ; good symbol counter
  399. usrem    ds    1
  400. srem    ds    1
  401. outfptr ds    1                    ; output filter pointer
  402.  
  403. tmp    ds    1
  404.  
  405.  
  406.     org    y:
  407.  
  408. zsample ds    1                    ; current zero crossing sample
  409. dsample ds    1                    ; previous decision sample
  410. pzsample ds    1                    ; current zero crossing sample
  411. pdsample ds    1                    ; previous decision sample
  412.  
  413.     endsec
  414.  
  415.  
  416. ;****************************
  417. ;*    M*BITS MODULO DATA    *
  418. ;****************************
  419.     section PAMData
  420.     xdef    N,inN,outN,rcos
  421.     xdef    insamp,outsamp,outfilt
  422.  
  423.     org    x:
  424.  
  425. ; PAM demod parameters
  426. N    equ    13                    ; samples per filter
  427. inN    equ    16                    ; input buffer lenght
  428. outN    equ    8                    ; output buffer lenght
  429.  
  430. insamp    ds    inN
  431. outfilt ds    N
  432.     ds    16-N
  433. outsamp ds    8
  434.  
  435.     org    y:
  436.  
  437. ; square root of raised cosine pulse filter constants
  438. ; beta = 6/16 = 0.375
  439. rcos    dc    -0.0082167989
  440.     dc     0.0071048900
  441.     dc     0.0254175599
  442.     dc    -0.0592829199
  443.     dc    -0.0434475299
  444.     dc     0.2999202999
  445.     dc     0.5512325000
  446.     dc     0.2999202999
  447.     dc    -0.0434475299
  448.     dc    -0.0592829199
  449.     dc     0.0254175599
  450.     dc     0.0071048900
  451.     dc    -0.0082167989
  452.  
  453.     endsec
  454.  
  455.     end
  456.